/*
 *  Copyright (C) 2010 romain
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.boc.botv.web.controller;

import com.boc.botv.common.Database;
import com.boc.botv.model.Bet;
import com.boc.botv.model.BetChoice;
import com.boc.botv.model.BetInstance;
import com.boc.botv.model.Category;
import com.boc.botv.model.SiteAccount;
import com.boc.botv.model.Transaction;
import com.boc.botv.model.User;
import com.boc.botv.service.BetManager;
import com.boc.botv.service.CategoryManager;
import com.boc.botv.service.PaymentMethodManager;
import com.boc.botv.service.SiteAccountManager;
import com.boc.botv.service.TransactionManager;
import com.boc.botv.service.UserManager;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

/**
 *
 * @author romain
 */
@Controller
@RequestMapping("/admin/")
@SessionAttributes("bet")
public class AdminController {

  @Autowired
  private BetManager betManager;
  @Autowired
  private PaymentMethodManager paymentMethodManager;
  @Autowired
  private UserManager userManager;
  @Autowired
  private CategoryManager categoryManager;
  @Autowired
  private TransactionManager transactionManager;
  @Autowired
  private SiteAccountManager siteAccountManager;
  private Map<String, Object> map = new HashMap<String, Object>();

  /**** Méthodes GET ****/
  @RequestMapping("index")
  public String adminHandler(Model model) {
    Database.startTransaction(true);
    map.put("categories", categoryManager.getChilds(0));
    map.put("title", "Administration");
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/index";
  }

  /**** Méthodes POST ****/
  @RequestMapping(value = "gestion-utilisateurs", method = RequestMethod.POST)
  public String getUserPage(Model model) {
    Database.startTransaction(true);
    List<User> user = userManager.getUsers();
    for (User u : user) {
      u.getPaymentMethod();
    }
    map.put("users", user);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/gestion-users";
  }

  @RequestMapping(value = "gestion-paris", method = RequestMethod.POST)
  public String getBetPage(Model model) {
    Database.startTransaction(true);
    List<Bet> bets = betManager.getBets();
    List<Category> categoryList = categoryManager.getCategory();
    Map<Integer, String> categoryMap = new HashMap<Integer, String>();
    for (int i = 0; i < categoryList.size(); i++) {
      categoryMap.put(categoryList.get(i).getId(), categoryList.get(i).getName());
    }
    for (int j = 0; j < bets.size(); j++) {
      bets.get(j).setSectionName(categoryMap.get(bets.get(j).getSubsection()));
    }
    map.put("bets", bets);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/gestion-bets";
  }

  @RequestMapping(value = "gestion-transactions", method = RequestMethod.POST)
  public String getTransactionPage(Model model) {
    Database.startTransaction(true);
    List<Transaction> transactions = transactionManager.getTransactions();
    for (Transaction tr : transactions) {
      int saId = tr.getSiteAccount().getId();
      int userId = tr.getUser().getId();
      SiteAccount sa = siteAccountManager.getAccount(saId);
      tr.setSiteAccount(sa);
      User u = userManager.getUser(userId);
      tr.setUser(u);
      tr.getSiteAccount().getName();
      tr.getUser().getLogin();
    }
    map.put("transactions", transactions);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/gestion-transactions";
  }

  @RequestMapping(value = "detailuser", method = RequestMethod.POST)
  public String getUserDetails(@RequestParam(value = "pid", required = true) String userId, Model model) {
    Database.startTransaction(true);
    User user = userManager.getUser(Integer.parseInt(userId));
    map.put("user", user);
    map.put("pm", user.getPaymentMethod());
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/detailuser";
  }

  @RequestMapping(value = "transactionuser", method = RequestMethod.POST)
  public String getTransactionUserDetails(@RequestParam(value = "pid", required = true) int userId, Model model) {
    Database.startTransaction(true);
    User user = userManager.getUser(userId);
    List<Transaction> transactions = transactionManager.getTransactions(user);
    for (Transaction tr : transactions) {
      tr.getSiteAccount().getName();
    }
    model.addAllAttributes(map);
    model.addAttribute("user", user);
    model.addAttribute("transactions", transactions);
    Database.closeTransaction();
    return "admin/transactionuser";
  }

  @RequestMapping(value = "editbet", method = RequestMethod.POST)
  public String getBetDetails(
          @RequestParam(value = "pid", required = true) int betId,
          @RequestParam(value = "name", required = false) String name,
          Model model) {
    Database.startTransaction(true);
    Bet bet = betManager.getBet(betId);
    Date now = new Date();
    boolean canAdd = now.before(bet.getStartTime());
    boolean canValid = now.after(bet.getEndTime());
    String betname = "";
    if (betId == 0) {
      betname = name;
    } else {
      betname = bet.getName();
    }
    List<BetChoice> betChoices = betManager.getChoices(betId);
    for (BetChoice bc : betChoices) {
      canValid &= !bc.isIsWinning();
    }
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
    String start = format.format(bet.getStartTime());
    String end = format.format(bet.getEndTime());
    map.put("start", start);
    map.put("end", end);
    map.put("betname", betname);
    map.put("betsection", bet.getSubsection());
    map.put("bet", bet);
    map.put("choices", betChoices);
    map.put("categories", categoryManager.getCategory());
    map.put("canAdd", canAdd);
    map.put("canValid", canValid);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/editbet";
  }

  @RequestMapping(value = "getfolders", method = RequestMethod.POST)
  public String getFolders(@RequestParam(value = "parentId", required = true) Integer parentId, Model model) {
    Database.startTransaction(true);
    map.put("categories", categoryManager.getChilds(parentId));
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/xml/getfolders";
  }

  @RequestMapping(value = "addfolder", method = RequestMethod.POST)
  public String addFolder(
          @RequestParam(value = "parentId", required = true) Integer parentId,
          @RequestParam(value = "name", required = true) String name,
          Model model) {
    Database.startTransaction(false);
    boolean r = categoryManager.addCategory(name, parentId);
    Category c = categoryManager.getCategory(name);
    map.put("lastId", c.getId());
    map.put("result", r ? "1" : "0");
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/xml/addfolder";
  }

  @RequestMapping(value = "paymentrefuse", method = RequestMethod.GET)
  public String refusePaymentMethod(@RequestParam(value = "pid", required = true) String pmId, Model model) {
    Database.startTransaction(false);
    boolean b = paymentMethodManager.refusePaymentMethod(Integer.parseInt(pmId));
    map.put("result", b ? "1" : "0");
    map.put("status", "0");
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/xml/paymentmethod";
  }

  @RequestMapping(value = "paymentnext", method = RequestMethod.GET)
  public String nextStepPaymentMethod(@RequestParam(value = "pid", required = true) String pmId, Model model) {
    Database.startTransaction(false);
    int status = paymentMethodManager.nextStepPaymentMethod(Integer.parseInt(pmId));
    map.put("result", status != -1 ? "1" : "0");
    map.put("status", status);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/xml/paymentmethod";
  }

  @RequestMapping(value = "removebets", method = RequestMethod.POST)
  public String removeBet(@RequestParam(value = "pids", required = true) int pmId, Model model) {
    Database.startTransaction(false);
    betManager.deleteBet(betManager.getBet(pmId));
//    map.put("result", status != -1 ? "1" : "0");
//    map.put("status", status);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/gestion-paris";
  }

  @RequestMapping(value = "saveOrUdpateBet", method = RequestMethod.POST)
  public String saveOrUdpateBet(@RequestParam(value = "pid", required = true) String pid,
          @RequestParam(value = "pname", required = true) String name,
          @RequestParam(value = "pdesc", required = true) String desc,
          @RequestParam(value = "pstatus", required = true) boolean pstatus,
          @RequestParam(value = "psection", required = true) Integer section,
          @RequestParam(value = "pstart", required = true) String start,
          @RequestParam(value = "pend", required = true) String end,
          Model model) {
    Database.startTransaction(false);
    User admin = userManager.getUser(1);
    Date creationDate = new Date();
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
    Date startDate = new Date();
    Date endDate = new Date();

    //int status = Integer.parseInt(pstatus);
    int id = Integer.parseInt(pid);
    //int section = Integer.parseInt(psection);

    try {
      startDate = format.parse(start);
      endDate = format.parse(end);
    } catch (Exception e) {
    }
    boolean actif = false;
    // actif
    if (pstatus) {
      actif = true;
    }
    boolean r = betManager.saveOrUpdate(admin, id, name, desc, creationDate, startDate, endDate, section, actif);
    model.addAttribute("result", r ? "1" : "0");
    Database.closeTransaction();
    return "/xml/boolean";
  }

  @RequestMapping(value = "setWinningChoice", method = RequestMethod.POST)
  public String setWinningChoice(
          @RequestParam(value = "pchid", required = true) int choiceId,
          Model model) {
    Database.startTransaction(false);
    boolean r = betManager.setWinningChoice(choiceId);
    model.addAttribute("result", r ? "1" : "0");
    Database.closeTransaction();
    return "/xml/boolean";
  }

  @RequestMapping(value = "newbet", method = RequestMethod.POST)
  public String createBet(
          @RequestParam(value = "pname", required = true) String name,
          @RequestParam(value = "psection", required = true) int psection,
          Model model) {
    Database.startTransaction(false);

    Date creation = new Date();
    Date start = new Date();
    start.setDate(creation.getDate() + 1);
    Date end = new Date();
    end.setDate(creation.getDate() + 3);
    User admin = userManager.getUser(1);
    Bet bet = new Bet(admin, name, "", creation, start, end, psection, false);
    betManager.createBet(bet);
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
    String starts = format.format(bet.getStartTime());
    String ends = format.format(bet.getEndTime());
    map.put("start", starts);
    map.put("end", ends);
    map.put("betname", name);
    map.put("betsection", bet.getSubsection());
    map.put("bet", bet);
    map.put("choices", bet.getBetChoices());
    map.put("categories", categoryManager.getCategory());
    map.put("canAdd", true);
    map.put("canValid", false);
    model.addAllAttributes(map);
    Database.closeTransaction();
    return "admin/editbet";
  }

  @RequestMapping(value = "newchoice", method = RequestMethod.POST)
  public String createChoice(
          @RequestParam(value = "pid", required = true) int pid,
          @RequestParam(value = "pchoix", required = true) String choice,
          Model model) {
    Database.startTransaction(false);
    Bet bet = betManager.getBet(pid);
    boolean r = betManager.addChoice(bet, choice);
    model.addAttribute("result", r ? "1" : "0");
    Database.closeTransaction();
    return "xml/boolean";
  }

  @RequestMapping(value="show-gamers", method=RequestMethod.POST)
  public String showGamers(
          @RequestParam(value = "pid", required = true) int pid,
          Model model) {
    Database.startTransaction(true);
    List<BetInstance> list = betManager.getGamesByBet(pid);
    for (BetInstance bi : list) {
      bi.getBetChoice().getLabel();
      bi.getBetChoice().isIsWinning();
      bi.getUser().getLogin();
    }
    model.addAllAttributes(map);
    model.addAttribute("games", list);
    Database.closeTransaction();
    return "admin/gamers";
  }
}
